package com.internetCafes.spms.common.config;

import com.internetCafes.spms.common.config.shiro.CustomSessionListener;
import com.internetCafes.spms.common.config.shiro.RedisCacheManager;
import com.internetCafes.spms.common.config.shiro.RedisSessionDAO;
import com.internetCafes.spms.common.config.shiro.ShiroSessionManager;
import com.internetCafes.spms.web.sys.oauth2.OAuth2Filter;
import com.internetCafes.spms.web.sys.oauth2.OAuth2Realm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.*;

/**
 * Shiro配置
 *
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2017-04-20 18:33
 */
@Configuration
public class ShiroConfig {


    /*@Bean("sessionManager")
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        //sessionManager.setSessionIdCookieEnabled(false);
        return sessionManager;
    }*/

    @Bean(name = "redisSessionDAO")
    public RedisSessionDAO redisSessionDAO() {
        return new RedisSessionDAO();
    }

    @Bean(name = "redisCacheManager")
    public RedisCacheManager redisCacheManager() {
        return new RedisCacheManager();
    }

    @Bean(name = "customSessionListener")
    public CustomSessionListener customSessionListener() {
        return new CustomSessionListener();
    }

    /**
     * @return
     * @see DefaultWebSessionManager
     */
    @Bean(name = "sessionManager")
    public DefaultWebSessionManager defaultWebSessionManager() {
        ShiroSessionManager sessionManager = new ShiroSessionManager();
        //用户信息必须是序列化格式，要不创建用户信息创建不过去，此坑很大，
//        sessionManager.setSessionDAO(redisSessionDAO());//如不想使用REDIS可注释此行
        Collection<SessionListener> sessionListeners = new ArrayList<>();
        sessionListeners.add(customSessionListener());
        sessionManager.setSessionListeners(sessionListeners);
        //单位为毫秒（1秒=1000毫秒） 3600000毫秒为1个小时
        sessionManager.setSessionValidationInterval(1000 * 60 * 30);
        //3600000 milliseconds = 1 hour
        sessionManager.setGlobalSessionTimeout(1000 * 60 * 30);
        //是否删除无效的，默认也是开启
        sessionManager.setDeleteInvalidSessions(true);
        //是否开启 检测，默认开启
        sessionManager.setSessionValidationSchedulerEnabled(true);
        /*//创建会话Cookie
        Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
        cookie.setName("WEBID");
        cookie.setHttpOnly(true);
        sessionManager.setSessionIdCookie(cookie);*/
        return sessionManager;
    }

    @Bean("securityManager")
    public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(oAuth2Realm);
        //securityManager.setSessionManager(sessionManager);
        //注入缓存管理器;
        //securityManager.setCacheManager(redisCacheManager());
        securityManager.setSessionManager(defaultWebSessionManager());

        return securityManager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        //oauth过滤
        Map<String, Filter> filters = new HashMap<>();
        filters.put("oauth2", new OAuth2Filter());
        shiroFilter.setFilters(filters);

        Map<String, String> filterMap = new LinkedHashMap<>();
        //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
        /**
         * anon（匿名）  org.apache.shiro.web.filter.authc.AnonymousFilter
         * authc（身份验证）       org.apache.shiro.web.filter.authc.FormAuthenticationFilter
         * authcBasic（http基本验证）    org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
         * logout（退出）        org.apache.shiro.web.filter.authc.LogoutFilter
         * noSessionCreation（不创建session） org.apache.shiro.web.filter.session.NoSessionCreationFilter
         * perms(许可验证)  org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
         * port（端口验证）   org.apache.shiro.web.filter.authz.PortFilter
         * rest  (rest方面)  org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
         * roles（权限验证）  org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
         * ssl （ssl方面）   org.apache.shiro.web.filter.authz.SslFilter
         * member （用户方面）  org.apache.shiro.web.filter.authc.UserFilter
         * user  表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe
         */
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/v2/*", "anon");
        filterMap.put("/swagger-resources/**", "anon");
        filterMap.put("/druid/**", "anon");
        filterMap.put("/api/**", "anon");
        filterMap.put("/sys/sendMobileCaptcha", "anon");
        filterMap.put("/sys/register", "anon");
        filterMap.put("/sys/recover", "anon");
        filterMap.put("/website/websiteArticleInfo/queryAll", "anon");
        filterMap.put("/website/websiteArticleInfo/selectAll", "anon");
        filterMap.put("/website/websiteArticleInfo/listAll", "anon");
        filterMap.put("/website/websiteArticleInfo/listOrg", "anon");
        filterMap.put("/website/websiteArticleInfo/info/**", "anon");
        filterMap.put("/website/websiteArticleInfo/byCode/**", "anon");
        filterMap.put("/website/websiteArticleInfo/getSubTitle", "anon");
        filterMap.put("/supplyAndDemand/supplyInfo/statistics", "anon");
        filterMap.put("/supplyAndDemand/supplyInfo/supplyAndDemandList", "anon");
        filterMap.put("/sys/login", "anon");
        filterMap.put("/sys/login/getTenantList/**", "anon");
        filterMap.put("/**/*.css", "anon");
        filterMap.put("/**/*.js", "anon");
        filterMap.put("/**/*.png", "anon");
        filterMap.put("/**/*.jpg", "anon");
        filterMap.put("/**/*.html", "anon");
        filterMap.put("/**/*.xlsx", "anon");
        filterMap.put("/**/*.doc", "anon");
        filterMap.put("/**/*.docx", "anon");
        filterMap.put("/fonts/**", "anon");
        filterMap.put("/plugins/**", "anon");
        filterMap.put("/common/**", "anon");
        filterMap.put("/adminlte/*", "anon");
        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/captcha.jpg", "anon");
        filterMap.put("/captcha", "anon");
        filterMap.put("/wx/sys/**", "anon");
        filterMap.put("/", "anon");
        filterMap.put("/pay/alipay/save", "anon");
        filterMap.put("/**", "oauth2");
        shiroFilter.setFilterChainDefinitionMap(filterMap);

        return shiroFilter;
    }

    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

}
